package com.gzx.plugin.tjzy.modular.call.api.service.impl;

import cn.dev33.satoken.stp.StpUtil;
import cn.hutool.core.collection.CollectionUtil;
import cn.hutool.http.Header;
import com.alibaba.fastjson2.JSON;
import com.alibaba.fastjson2.JSONObject;
import com.gzx.plugin.tjzy.modular.call.api.bo.GzxHtCallApiBo;
import com.gzx.plugin.tjzy.modular.call.api.service.GzxHtCallApiService;
import lombok.RequiredArgsConstructor;
import lombok.extern.slf4j.Slf4j;
import org.apache.commons.lang3.StringUtils;
import org.springframework.beans.factory.annotation.Value;
import org.springframework.stereotype.Service;
import vip.xiaonuo.auth.core.util.StpLoginUserUtil;
import vip.xiaonuo.common.cache.CommonCacheOperator;
import vip.xiaonuo.common.exception.CommonException;
import vip.xiaonuo.common.util.CommonCryptogramUtil;
import vip.xiaonuo.common.util.CommonHttpUtil;

import java.util.*;

/**
 * @author zjt
 * @description
 * @date 2025/3/27 18:41
 */
@Service
@Slf4j
@RequiredArgsConstructor
public class GzxHtCallApiServiceImpl implements GzxHtCallApiService {

    @Value("${call.ht.loginName}")
    private String loginName;

    @Value("${call.ht.password}")
    private String password;

    @Value("${call.ht.task-add-url}")
    private String taskAddUrl;

    @Value("${call.ht.task-addTo-url}")
    private String taskAddToUrl;

    @Value("${call.ht.task-switch-url}")
    private String taskSwitchUrl;

    @Value("${call.ht.task-update-url}")
    private String taskUpdateUrl;

    @Value("${call.ht.listen-voice-url.start}")
    private String listenVoiceStartUrl;

    @Value("${call.ht.listen-voice-url.stop}")
    private String listenVoiceStopUrl;

    @Value("${call.ht.callback-url.receipt}")
    private String receiptCallBackUrl;

    @Value("${call.ht.callback-url.voice-to-text}")
    private String voiceTextCallBackUrl;

    @Value("${call.ht.listen-login-account}")
    private String listenLoginAccount;

    @Value("${call.ht.listen-login-password}")
    private String listenLoginPassword;

    @Value("${call.ht.receipt.sync.url}")
    private String receiptSyncUrl;

    @Value("${call.ht.receipt.sync.tenant}")
    private String receiptSyncTenant;

    @Value("${call.ht.receipt.sync.limit}")
    private Integer receiptSyncLimit;

    @Value("${call.ht.receipt.sync.secret}")
    private String receiptSyncSecret;

    private final CommonCacheOperator cacheOperator;

    /**
     * 开始预测外呼
     *
     * @return
     */
    @Override
    public String startPreCall(GzxHtCallApiBo predictHttpApiBo) {
        log.info("调用恒天开始预测外呼接口");
        if (!StpUtil.hasRole("mediator")) {
            throw new CommonException("无预测外呼权限");
        }
        String taskId = createTask(predictHttpApiBo);
        addTaskData(taskId, predictHttpApiBo);
        //开启任务
        switchTask(taskId, 1);
        return taskId;
    }

    /**
     * 预测外呼任务状态修改
     *
     * @param taskId
     * @param type
     * @return
     */
    @Override
    public void switchTask(String taskId, Integer type) {
        Map<String, Object> dataMap = new HashMap<>();
        dataMap.put("LoginName", loginName);
        dataMap.put("PassWord", password);
        dataMap.put("TaskId", taskId);
        dataMap.put("Type", type);
        String reqStr = JSON.toJSONString(dataMap);
        CommonHttpUtil.post(taskSwitchUrl, null, reqStr, "调用恒天修改任务状态接口，任务类型--->" + type);
    }

    /**
     * 开始监听坐席
     *
     * @param agentExtNo
     */
    @Override
    public void startListen(String agentExtNo) {
        Map<String, String> reqMap = Map.of("extAgentId", agentExtNo, "callBackUrl", voiceTextCallBackUrl);
        CommonHttpUtil.post(listenVoiceStartUrl, Map.of(Header.AUTHORIZATION.getValue(), generateListenToken()), JSON.toJSONString(reqMap), "调用恒天开始监听坐席通话接口");
    }

    /**
     * 停止监听坐席
     *
     * @param agentExtNo
     */
    @Override
    public void stopListen(String agentExtNo) {
        Map<String, String> reqMap = Map.of("extAgentId", agentExtNo);
        CommonHttpUtil.post(listenVoiceStopUrl, Map.of(Header.AUTHORIZATION.getValue(), generateListenToken()), JSON.toJSONString(reqMap), "调用恒天开始监听坐席通话接口");
    }

    /**
     * 根据CallId保存当前登录者信息
     *
     * @param callId
     */
    @Override
    public void setCallUser(String callId) {
        cacheOperator.setCatchString("CallId_" + callId, StpLoginUserUtil.getLoginUser().getId(), 1800);
    }

    /**
     * 设置主叫号码
     *
     * @param callNumber
     */
    @Override
    public void setCallNumber(String callNumber) {
        cacheOperator.setCatchString("CallNumber_" + StpLoginUserUtil.getLoginUser().getId(), callNumber);
    }

    /**
     * 获取当前坐席的主叫号码
     *
     * @return
     */
    @Override
    public String getCallNumber() {
        return cacheOperator.getCatchString("CallNumber_" + StpLoginUserUtil.getLoginUser().getId());
    }

    /**
     * 调解员状态上报
     *
     * @param status
     * @return
     */
    @Override
    public void seatsSeatStatus(String status) {

    }

    private String createTask(GzxHtCallApiBo predictHttpApiBo) {
        Map<String, Object> dataMap = new HashMap<>();
        dataMap.put("LoginName", loginName);
        dataMap.put("PassWord", password);
        dataMap.put("State", "1");
        //0：多人预测外呼 1：单人预测外呼 6：机器人优先
        dataMap.put("DialType", predictHttpApiBo.getCallType());
        if (predictHttpApiBo.getCallType() == 0) {
            dataMap.put("QueueEName", predictHttpApiBo.getQueueCode());
        }
        dataMap.put("TemplateID", "000001");
        dataMap.put("CallThreads", predictHttpApiBo.getCallThread());
        dataMap.put("DataType", "XMD");
        dataMap.put("CallPhone", predictHttpApiBo.getCallPhone());
        //单人预测
        if (predictHttpApiBo.getCallType() == 1) {
            //坐席工号
            dataMap.put("AgentWorkid", StpLoginUserUtil.getLoginUser().getAccount());
        }
        //请求主体信息
        String reqStr = JSON.toJSONString(dataMap);
        String responseJson = CommonHttpUtil.post(taskAddUrl, null, reqStr, "调用恒天预测外呼任务创建接口");
        JSONObject jsonObject = JSON.parseObject(responseJson);
        return jsonObject.get("Data").toString();
    }

    /**
     * 追加任务数据
     *
     * @param taskId
     * @param predictHttpApiBo
     * @return
     */
    private void addTaskData(String taskId, GzxHtCallApiBo predictHttpApiBo) {
        if (StringUtils.isBlank(taskId)) {
            throw new CommonException("TaskId为空，任务追加失败");
        }
        Map<String, String> bussinesMap = predictHttpApiBo.getBussinesMap();
        if (CollectionUtil.isNotEmpty(bussinesMap)) {
            List<Map<String, String>> dataList = new ArrayList<>();
            for (String key : bussinesMap.keySet()) {
                Map<String, String> dataMap = new HashMap<>();
                dataMap.put("CallPhone", predictHttpApiBo.getCallPhone());
                dataMap.put("Phone", key);
                //透传字段
                dataMap.put("Business", bussinesMap.get(key));
                dataList.add(dataMap);
            }
            //请求主体信息
            Map<String, Object> dataMap = new HashMap<>();
            dataMap.put("LoginName", loginName);
            dataMap.put("PassWord", password);
            dataMap.put("TaskId", taskId);
            dataMap.put("TemplateID", "000001");
            //0：多人预测外呼 1：单人预测外呼 6：机器人优先
            dataMap.put("DialType", predictHttpApiBo.getCallType());
            dataMap.put("CallBackUrl", receiptCallBackUrl);
            dataMap.put("case", dataList);
            String reqStr = JSON.toJSONString(dataMap);
            CommonHttpUtil.post(taskAddToUrl, null, reqStr, "调用恒天预测外呼追加任务数据接口");
        }
    }

    private String generateListenToken() {
        String digestStr = CommonCryptogramUtil.doMd5(listenLoginAccount + listenLoginPassword);
        return "Basic " + Base64.getEncoder().encodeToString((listenLoginAccount + ":" + digestStr).getBytes(java.nio.charset.StandardCharsets.UTF_8));
    }
}
